package VNF_DelaySBA_small;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Random;
import java.util.Set;

import com.net2plan.interfaces.networkDesign.Link;
import com.net2plan.interfaces.networkDesign.NetPlan;
import com.net2plan.interfaces.networkDesign.Node;

public class CreateNetPlan {
	public static final int numberOfAllVNFTypes = 3;
	public static final int numberOfThreadVNFs = 3;
	public static NetPlan createOneNetplan(){
		NetPlan netplan = new NetPlan();
		netplan = createNode(netplan);
		netplan = createLink(netplan);
		//整个请求的延时，由节点和链路形成
		netplan.setAttribute("DelayTime", "0");
		//请求对延时的阈值要求
		int threadTime = 0;
		for(Node node:netplan.getNodes()) {
			int vnfType = Integer.valueOf(node.getAttribute("VNF"));
			if(vnfType!=0) {
				threadTime+=(vnfType+1)*5*numberOfThreadVNFs;
			}
		}
		threadTime+=10;
		netplan.setAttribute("ThreadTime", String.valueOf(threadTime));
		return netplan;
	}
	public static NetPlan createNode(NetPlan netplan){
		List<Node> nodes = new ArrayList<Node>();
		Random r = new Random();
		//每个请求最多有2个VNF节点，所以总节点数3-4
		int N = ((int)(Math.random()*2))+3;
		//坐标不重要
		double xmax = 100;
		double xmin = 0;
		double ymax = 100;
		double ymin = 0;
		for (int n = 0; n < N; n++)
		{
			double xCoord = xmin + (xmax - xmin) * r.nextDouble();
			double yCoord = ymin + (ymax - ymin) * r.nextDouble();
			Node node = netplan.addNode(xCoord, yCoord, "Node " + n, null);
			nodes.add(node);
		}
		return netplan;
	}

	public static NetPlan createLink(NetPlan netplan) {
		int numberofnodes = netplan.getNumberOfNodes();
		//源节点单独拿出来
		Node sourcenode = netplan.getNode(0);
		
		/*
		 * VNF表示这个节点需要的VNF类型
		 * deployed表示这个节点有没有被映射了
		 * MappdeNode表示这个节点被映射到哪个无力节点上了
		 */
		sourcenode.setAttribute("VNF", "0");
		sourcenode.setAttribute("MappedNode", "0");
		
		//目的节点单独考虑
		Node destinationnode = netplan.getNode(numberofnodes-1);
		destinationnode.setAttribute("VNF", "0");
		destinationnode.setAttribute("MappedNode", "0");
		/*
		 * 中间节点需要vnf，每个节点上的VNF种类不重复，用hashset实现
		 * 一共有3中VNF，1-3来表征
		 */
		Set<Integer> vnftypeset = new HashSet<Integer>();
		vnftypeset.add(0);
		for (int i=1;i<numberofnodes-1;i++){
			Node middlenode = netplan.getNode(i);
			int vnftype = 0;
			while(true) {
				vnftype = 1+(int)(Math.random()*numberOfAllVNFTypes);
				if(!vnftypeset.contains(vnftype)) {
					vnftypeset.add(vnftype);
					break;
				}
			}
			middlenode.setAttribute("VNF", String.valueOf(vnftype));
			middlenode.setAttribute("MappedNode", "0");	
		}
			
		//请求速率[10-100]
		double p =Math.random()*91+10;
		 //两个相邻节点之间创建一条link
		 for (int i=0;i<=numberofnodes-2;i++){ 
			 //请求中link的长度不重要
			 double dist = netplan.getNodePairEuclideanDistance(netplan.getNode(i), netplan.getNode(i+1));
			 netplan.addLink(netplan.getNode(i), netplan.getNode(i+1), p, dist, 1, null, netplan.getNetworkLayerDefault()).setCapacity(p);
		 }
		 List<Link> requestLinkList = netplan.getLinks(netplan.getNetworkLayerDefault());
		 for(Link link:requestLinkList) {
			 link.setAttribute("pathlength", "0.0");
		 }
		 return netplan;
	}
}
